iT邦幫忙

2026 iThome 鐵人賽

DAY 4
1

原始碼合併完後,要如何確認組合後的程式正常運作?

這一篇會從「整合」的目的開始,逐步說明需要確認的事情。

整合的定義

各自完成的原始碼,放在一起後不一定能照原本的預期運作。整合的目的,就是把這些原始碼組合起來,確認它們是否能一起滿足需求。

書中對整合的定義是:

The act of combining separate source-code artifacts to determine how they work as a whole.

也就是把不同部分的原始碼組合起來,確認它們放在一起後會如何運作。

這些原始碼可能來自本機和共享目錄,也可能來自不同分支。把自己和其他人的修改放在一起後,就需要確認程式的行為是否符合預期。

假設 A 開發者修改了共用功能,滿足自己的需求,卻讓依賴這段功能的 B 出現不符合預期的結果。以下三張圖說明修改前、修改後,以及把行為改回去的影響。

  1. 修改前:B 依賴原本的行為,A 的需求需要調整這段功能。

https://ithelp.ithome.com.tw/upload/images/20260918/20102562h6BkDy10Iq.png

  1. A 修改後:A 的需求滿足了,B 的功能卻不符合預期。

https://ithelp.ithome.com.tw/upload/images/20260918/20102562HZday8OxhR.png

  1. 如果 B 把行為改回去:恢復 B 原本依賴的行為,又會影響 A。

https://ithelp.ithome.com.tw/upload/images/20260918/2010256255o7OKHY6i.png

這就是俗稱的「改 A 壞 B」。即使沒有直接修改 B 的原始碼,共用功能的行為改變也可能影響 B。所以,雙方需要一起確認組合後的程式要滿足哪些需求,再決定如何修改和驗證。

那麼,要如何確認組合後的程式符合預期?

建置的定義與範圍

只確認原始碼合併成功,還不知道程式是否能編譯、功能是否符合預期,以及是否能在需要的環境運作。要確認這些事情,可以先了解建置(Build)包含哪些步驟。

書中對建置的定義是:

A set of activities performed to generate, test, inspect, and deploy software.

這裡的建置指的是一組活動,範圍不只有編譯,還可以包含測試、程式碼檢查與部署。

以下整理編譯、測試、程式碼檢查與部署各自要確認的問題。團隊可以先決定整合需要確認哪些項目,再安排對應的步驟。流程可以按照專案需求調整,不必每次建置都執行相同的步驟。

建置項目 要確認的問題
編譯(Compilation) 原始碼和需要的依賴,是否能順利通過編譯並產生預期的檔案?
測試(Testing) 執行程式後,行為與結果是否符合預期?
程式碼檢查(Inspection) 原始碼是否符合約定的規則,有哪些需要注意的品質問題?
部署(Deployment) 程式與必要設定是否放進指定環境,並在那裡啟動、運作?

接下來分別說明編譯、測試、程式碼檢查與部署的目的和做法。

編譯

需要編譯的專案,即使各自修改時都能通過編譯,也還需要確認合併後的原始碼與依賴是否能一起編譯。如果編譯失敗,就無法產生後續測試或部署需要的檔案。

先準備好整合後的原始碼和需要的依賴,再執行專案的編譯步驟,確認是否成功產生預期的檔案。如果編譯失敗,就按照錯誤訊息找出問題,修正後再重新編譯。不同語言與工具的處理方式不同,也不是所有專案都會產生獨立的執行檔。

不過,通過編譯並產生檔案,還不能證明程式執行後會符合需求。

測試

例如,需求是輸出 Hello World,程式實際輸出的卻是 null。即使程式能執行,也沒有完成原本的要求。

測試的目的,就是確認程式的行為與結果是否符合需求。執行之前要先說清楚預期結果,再執行程式,比較實際結果和預期是否一致。除了這次修改想達成的行為,也要確認受影響的原有功能是否還符合需求。

可以從幾個方向來確認:換成不同的輸入,結果是否還符合預期?遇到不合法的輸入,是否按照預期處理?其他呼叫這段程式的地方,是否還能正常運作?這些都是決定驗證範圍時需要考慮的問題。

各個部分的功能和組合後的行為,需要分別驗證。以 Day 3 的例子來說,需要驗證的是 A、B 與 C 三份修改合併後的程式。即使 A、B 修改後的程式原本各自通過測試,也不能直接證明加入 C 修改後的行為符合需求。

如果實際結果和預期不同,就要先找出原因,確認程式行為和測試的預期結果是否符合需求,再修改並重新執行相關測試。

測試通過,表示程式在測試過的情境下符合預期。還沒測試的情境,需要另外驗證。

程式碼檢查

程式能正常運作,原始碼卻不一定容易看懂或修改。功能測試用來確認程式執行後的行為,程式碼檢查則幫助團隊找出程式結構和寫法上的問題。

破窗效應」認為,環境中的混亂如果一直沒有人處理,就可能出現更多破壞秩序的行為。從這個觀點來看,已知的原始碼問題如果一直放著不管,團隊也可能慢慢覺得這樣寫沒什麼關係。所以,檢查發現問題後,就得馬上檢視與處理。

團隊可以先定義好要遵守哪些規則,再用工具檢查原始碼格式、重複原始碼和複雜度。不符合規則的地方,就按照規則修改。工具提供的分析結果,則要看過原始碼後,再判斷是否需要調整。

例如,複雜度偏高不代表功能有錯。如果這段程式確實不好理解或修改,可以考慮拆成幾個小單元,讓每個單元負責的事情更清楚。修改後,再執行測試,確認原本的行為沒有改變。

部署

程式在開發者的電腦上能正常運作,不代表換到另一個環境也能正常運作,這就是俗稱的「在我電腦上都沒有問題」。部署的目的,是把程式安裝或更新到指定環境,讓它能在那裡執行,提供給需要使用或測試的人。

要部署到哪個環境,要看接下來的流程。例如,如果需要由測試人員驗證功能,就可以先把程式部署到測試環境。

部署時,要先準備好執行環境、程式需要的依賴和設定,再把程式安裝或更新到指定環境。部署完成後,除了確認程式是否能啟動,也要驗證功能是否符合預期。

建置腳本

如果每次建置都靠人工記住操作步驟,就可能漏做檢查,或因為順序不同而得到不同結果。建置腳本把這些步驟固定下來,讓團隊能用相同的方式重複執行。

整理腳本前,先確認要整合的版本、需要產生的檔案,以及各項驗證的預期結果,再安排步驟,並記錄需要的工具、依賴和設定。如果流程分成多個階段,也要確認前一階段產生的檔案是否能交給下一階段使用,以及驗證結果對應哪個版本。

**腳本內部可以複雜,啟動方式應該簡單。**準備好環境後,開發者應該能用一個指令啟動需要的流程,並從執行結果知道哪些步驟完成、哪些失敗,以及哪些還沒執行。

驗證結果的記錄

取得最新版本、準備繼續開發之前,要先知道這個版本做過哪些驗證、結果如何。原始碼已經合併、能夠啟動,不代表受影響的功能都符合需求。如果沒有留下驗證紀錄,其他成員就無法直接確認這些資訊。

如果開發者把錯誤的行為當成預期行為,新功能就可能依賴這個錯誤。等到錯誤被修正,後來開發的功能也可能需要一起修改和驗證。先查看驗證紀錄,可以避免在不知道已有檢查失敗的情況下,繼續依賴這個版本開發。

因此,執行驗證後,要記錄並分享驗證的版本、檢查項目與結果,包括哪些通過、哪些失敗,以及哪些還沒完成。讓其他成員取得原始碼時,也能查到對應的紀錄。

查看紀錄時,如果相關檢查還沒完成,就還不能把這個版本當成已通過驗證。如果檢查失敗,就要先找出原因並處理問題。即使全部通過,也要看檢查涵蓋哪些情況,不能把沒有測試過的行為當成已經確認正確。

小結

整合不只是把原始碼放在一起,還要按照專案需求,透過編譯、測試、程式碼檢查與部署,確認組合後的程式是否符合預期。把這些步驟整理成容易執行的腳本,能讓團隊用相同的方式重複驗證。記錄驗證的版本、項目與結果,則能讓其他成員有依據判斷這個版本是否適合繼續使用。

不過,當完成手上的任務後,其他開發者就能立刻取得已通過整合驗證的版本嗎?事實上並沒有這麼簡單,Day 5 會接著討論這個問題。

參考資料


上一篇
Day 03:分支與整合
下一篇
Day 05:開發者之間的距離
系列文
重新認識主幹開發(Trunk-Based Development)6
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言